package com.dd.stack.redis.controller;

import com.dd.stack.common.util.Result;
import com.dd.stack.common.util.response.ApiResponse;
import com.dd.stack.redis.config.redisConfig.lock.RedisDistributedLockUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.UUID;

/**
 * @Author liuxianmeng
 * @CreateTime 2025/1/31 18:22
 * @Description Redis分布式锁测试
 */
@Slf4j
@RestController
@RequiredArgsConstructor
@Api(tags = "Redis分布式锁测试")
@RequestMapping("/redis")
public class LockController {

    @Autowired
    private RedisDistributedLockUtil redisDistributedLockUtil;

    @GetMapping("/lock/simple")
    @ApiOperation("获取分布式锁执行操作后释放")
    public ApiResponse<?> lock(@RequestParam String lockKey) {
        // 生成唯一的请求ID
        String requestId = UUID.randomUUID().toString();
        // 尝试获取锁，锁过期时间为10秒，等待时间为1秒
        boolean isLocked = redisDistributedLockUtil.tryLock(lockKey, requestId, 10000, 1000);
        if (isLocked) {
            try {
                // 执行业务逻辑
                System.out.println("Lock acquired: " + lockKey);
                // 模拟业务逻辑处理时间
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                // 释放锁
                boolean isReleased = redisDistributedLockUtil.releaseLock(lockKey, requestId);
                System.out.println("Lock released: " + lockKey + ", Released: " + isReleased);
            }
            return ApiResponse.success("Lock acquired and released successfully!");
        } else {
            return ApiResponse.error("Failed to acquire lock within the specified time!");
        }
    }

    @GetMapping("/lock/redisson/general")
    @ApiOperation("创建订单（Redisson简单使用场景）")
    public ApiResponse<?> createOrder(String orderId) {
        String lockKey = "order_lock:" + orderId;

        redisDistributedLockUtil.executeWithLock(lockKey, 10, () -> {
            // 这里是需要加锁的业务逻辑
            System.out.println("开始处理订单: " + orderId);

            // 模拟业务处理
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }

            System.out.println("订单处理完成: " + orderId);
            return null; // 无返回值
        });

        return ApiResponse.success();
    }

    @GetMapping("/lock/redisson/")
    @ApiOperation("公平锁 按照线程的请求顺序给予锁")
    public ApiResponse<?> processPayment(String paymentId) {
        String lockKey = "payment_lock";

        redisDistributedLockUtil.executeWithFairLock(lockKey, 30, 10, () -> {
            // 公平处理支付请求
            System.out.println("开始处理支付: " + paymentId);

            // 模拟支付处理
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }

            System.out.println("支付处理完成: " + paymentId);
            return null;
        });

        return ApiResponse.success();
    }
}
